﻿// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved
// Developer:  Michael Antonio
using System;
using System.Collections.Generic;

namespace MichMan.Utilities.Requests
{
    /// <summary>
    /// Restricts the operations allowed on a request
    /// </summary>
    public class CacheRestrictor : CacheWrapper
    {
        /// <summary>
        /// Mode for cache restriction
        /// </summary>
        [Flags]
        public enum CacheRestrictorMode
        {
            /// <summary>
            /// Prevents all operations on a cache
            /// </summary>
            NoCache = 0,
            /// <summary>
            /// Allows reading from a cache
            /// </summary>
            Read = 1,
            /// <summary>
            /// Allows writing to a cache
            /// </summary>
            Write = 2,
            /// <summary>
            /// Allows reading and writing to a cache
            /// </summary>
            ReadWrite = 3
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CacheRestrictor"/> class.
        /// </summary>
        /// <param name="wrapped">The wrapped cache.</param>
        /// <param name="mode">The mode.</param>
        public CacheRestrictor(ICache wrapped, CacheRestrictorMode mode)
        {
            _wrapped = wrapped;
            Write = (mode & CacheRestrictorMode.Write) != 0;
            Read = (mode & CacheRestrictorMode.Read) != 0;
        }

        private readonly ICache _wrapped;


        protected override ICache GetWrapped()
        {
            return _wrapped;
        }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="CacheRestrictor"/> is writable.
        /// </summary>
        /// <value><c>true</c> if write; otherwise, <c>false</c>.</value>
        public bool Write { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="CacheRestrictor"/> is readable.
        /// </summary>
        /// <value><c>true</c> if read; otherwise, <c>false</c>.</value>
        public bool Read { get; set; }

        #region ICache
        /// <summary>
        /// Gets the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <returns></returns>
        public override object Get(string key)
        {
            return Read ? base.Get(key) : null;
        }

        /// <summary>
        /// Inserts the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="o">The object.</param>
        /// <param name="lifetime">The lifetime.</param>
        /// <returns></returns>
        public override bool Insert(string key, object o, TimeSpan? lifetime)
        {
            return Write ? base.Insert(key, o, lifetime) : false;
        }

        /// <summary>
        /// Deletes the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        public override void Delete(string key)
        {
            if (Write)
            {
                base.Delete(key);
            }
        }
        /// <summary>
        /// Removes everything from the cache.
        /// </summary>
        public override void Clear()
        {
            if (Write)
            {
                 base.Clear();
            }
        }
        #endregion ICache
    }
}
